/*
 *  mih_event_service.c
 *  MIHF
 *
 *  Created by injae song on 11. 3. 4..
 *  Copyright 2011 KyungHee Univ. All rights reserved.
 *
 */

#include "mih_event_service.h"

void mih_user_event_indication(mih_message *message, void *_user)
{
	mih_user *user = (mih_user*)_user;
	char *mih_frame;
	
	mih_frame = mih_message_serialize(message);
	bufferevent_write(user->ev_buf, mih_frame, MIH_HEADER_SIZE + message->header->payloadlength);
}

void mih_event_service_dispatch( mih_message* msg, mih_user *mih)
{
 

}

void mih_event_service_process_indication(mih_message* msg, mih_transaction_sm *sm) {
	
    mihf *mih = sm->mih;
	
	switch(msg->header->aid) {
		case MIH_Link_Detected:
			warn("link detected\n");
			break;
		case MIH_Link_Up:
			warn("link up\n");
			break;
		case MIH_Link_Down:
			warn("link down\n");
			break;
		case MIH_Link_Parameters_Report:
			warn("link parameters report\n");
			break;
		case MIH_Link_Going_Down:
			warn("link going down\n");
			break;
		case MIH_LINK_HANDOVER_IMMINENT:
			warn("link handover imminent\n");
			break;
		case MIH_Link_Handover_Complete:
			warn("link handover complete\n");
			break;
		case MIH_Link_PDU_Transmit_Status:
			warn("link pdu transmit status\n");
			break;
	}
	
    mih_event_dispatch_local_event(msg, mih);
	
	return;
}

void mih_event_dispatch_local_event(mih_message *message, mihf* mih) {
    
	mih_event* evt;
    mih_event_indication_callback* callback;
	
	int ev_aid = message->header->aid;
    
    for(ListElmt *elem = list_head(&mih->Event_Service); elem!=NULL; elem = list_next(elem))
    {
        evt = (mih_event*)list_data(elem);
        
        if(evt->type == ev_aid)
        {
           
            callback=evt->callback;
            
            if( callback!= NULL)
                callback->cb(message, callback->cb_arg);
         
        }
        
    }

}

void mih_events_unsubscribe_event(mihf *mih, MIH_EVT_LIST ev, void* cb_arg) 
{
    
    mih_event *evt;
    mih_event *temp;
    ListElmt *prev=NULL;
    
    for(ListElmt *elem = list_head(&mih->Event_Service); elem!=NULL; elem = list_next(elem))
    {
        evt = (mih_event*)list_data(elem);
        
        if(evt->type == ev)
        {
            if(evt->callback->cb_arg == cb_arg)
            {
                free(evt->callback->cb_arg);
                evt->callback = NULL;
                
                list_rem_next(&mih->Event_Service, prev, (void*)temp);
            }
        }
        
        prev = elem;
    }
    
	return;
}

void mih_events_unsubscribe_all_events(mihf *mih, void *cb_arg) {
    
	mih_event *evt;
	
    for(ListElmt *elem = list_head(&mih->Event_Service); elem!=NULL; elem = list_next(elem))
    {
        evt = (mih_event*)list_data(elem);
        
        mih_events_unsubscribe_event(mih, evt->type, cb_arg);
    }
    
	return;
}